package com.mjfeed.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mjfeed.entity.Admin;
import com.mjfeed.entity.Permission;
import com.mjfeed.entity.Role;
import com.mjfeed.service.AdminService;
import com.mjfeed.util.Pagination;
import com.mjfeed.util.ParamBean;
import com.mjfeed.util.QueryCondition;

@Service("adminService")
public class AdminServiceImpl extends BaseServiceImpl implements AdminService {

	@Transactional(readOnly = true)
	public Admin getAdminByUsername(String username) {
		Admin admin = null;
		admin = (Admin)getUniqueResultByJpql("from Admin where username=?", username);
		return admin;
	}
	
	@Transactional(readOnly = true)
	public Admin getCurrent() {
		Subject subject = SecurityUtils.getSubject();
		if (subject != null && subject.getPrincipal() != null) {
			String username = subject.getPrincipal().toString();
			if (username != null) {
				return getAdminByUsername(username);
			}
		}
		return null;
	}
	
	@Transactional(readOnly = true)
	public Pagination<Admin> getPagination(ParamBean paramBean) {
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		if (StringUtils.isNotBlank(paramBean.getKeyword())) {
			queryConditions.add(new QueryCondition(paramBean.getField(), QueryCondition.LK, paramBean.getKeyword()));
		}
		String orderBy = "order by id desc";
		Pagination<Admin> pagination = (Pagination<Admin>)getPagination(Admin.class, queryConditions, orderBy, paramBean.getPage(), paramBean.getPageSize());
		pagination.setPageHtml(paramBean.getUrl());
		return pagination;
	}
	
	@Transactional(readOnly = true)
	public Pagination<Permission> getPermissionPage(ParamBean paramBean) {
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		if (StringUtils.isNotBlank(paramBean.getKeyword())) {
			queryConditions.add(new QueryCondition(paramBean.getField(), QueryCondition.LK, paramBean.getKeyword()));
		}
		String orderBy = "order by orders asc";
		Pagination<Permission> pagination = (Pagination<Permission>)getPagination(Permission.class, queryConditions, orderBy, paramBean.getPage(), paramBean.getPageSize());
		pagination.setPageHtml(paramBean.getUrl());
		return pagination;
	}
	
	@Transactional(readOnly = true)
	public Pagination<Role> getRolePage(ParamBean paramBean) {
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		if (StringUtils.isNotBlank(paramBean.getKeyword())) {
			queryConditions.add(new QueryCondition(paramBean.getField(), QueryCondition.LK, paramBean.getKeyword()));
		}
		String orderBy = "order by id desc";
		Pagination<Role> pagination = (Pagination<Role>)getPagination(Role.class, queryConditions, orderBy, paramBean.getPage(), paramBean.getPageSize());
		pagination.setPageHtml(paramBean.getUrl());
		return pagination;
	}

	@Transactional(readOnly = true)
	public Set<Role> getRoles(Admin admin) {
		if (admin == null) {
			return null;
		}
		Admin padmin = null;
		if (admin.getId() != null) {
			padmin = getById(Admin.class, admin.getId());
		}
		if (StringUtils.isNotEmpty(admin.getUsername())) {
			padmin = getAdminByUsername(admin.getUsername());
		}
		return padmin.getRoles();
	}

	@Transactional(readOnly = true)
	public Set<Permission> getPermissions(Admin admin) {
		Set<Permission> permissions = new HashSet<Permission>();
		Set<Role> roles = getRoles(admin);
		if (roles != null && roles.size() > 0) {
			for (Role role : roles) {
				permissions.addAll(role.getPermissions());
			}
			return permissions;
		}
		
		return null;
	}
	
	@Transactional(readOnly = true)
	public boolean usernameExists(String username) {
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("username",QueryCondition.EQ,username));
		Long count = getRecordCount(Admin.class, queryConditions);
		return (count != null && count > 0) ? true : false;
	}
}
